package com.websystique.springboot.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;

import com.websystique.springboot.model.User;
import com.websystique.springboot.service.UserService;
import com.websystique.springboot.util.CustomErrorType;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/api")
public class RestApiController
{
    @Autowired
    UserService userService;
    
    // -------------------Retrieve All Users---------------------------------------------
    
    @GetMapping("/user/")
    public ResponseEntity<List<User>> listAllUsers()
    {
        List<User> users = userService.findAllUsers();
        if (users.isEmpty())
        {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
        return new ResponseEntity<List<User>>(users, HttpStatus.OK);
    }
    
    // -------------------Retrieve Single User------------------------------------------
    
    @GetMapping("/user/{id}")
    public ResponseEntity<?> getUser(@PathVariable("id") long id)
    {
        log.info("Fetching User with id {}", id);
        User user = userService.findById(id);
        if (user == null)
        {
            log.error("User with id {} not found.", id);
            return new ResponseEntity<>(new CustomErrorType("User with id " + id + " not found"), HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<User>(user, HttpStatus.OK);
    }
    
    // -------------------Create a User-------------------------------------------
    
    @PostMapping("/user/")
    public ResponseEntity<?> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder)
    {
        log.info("Creating User : {}", user);
        
        if (userService.isUserExist(user))
        {
            log.error("Unable to create. A User with name {} already exist", user.getName());
            return new ResponseEntity<>(new CustomErrorType("Unable to create. A User with name " + user.getName() + " already exist."), HttpStatus.CONFLICT);
        }
        userService.saveUser(user);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ucBuilder.path("/api/user/{id}").buildAndExpand(user.getId()).toUri());
        return new ResponseEntity<String>(headers, HttpStatus.CREATED);
    }
    
    // ------------------- Update a User ------------------------------------------------
    
    @PutMapping("/user/{id}")
    public ResponseEntity<?> updateUser(@PathVariable("id") long id, @RequestBody User user)
    {
        log.info("Updating User with id {}", id);
        
        User currentUser = userService.findById(id);
        
        if (currentUser == null)
        {
            log.error("Unable to update. User with id {} not found.", id);
            return new ResponseEntity<>(new CustomErrorType("Unable to upate. User with id " + id + " not found."), HttpStatus.NOT_FOUND);
        }
        
        currentUser.setName(user.getName());
        currentUser.setAge(user.getAge());
        currentUser.setSalary(user.getSalary());
        
        userService.updateUser(currentUser);
        return new ResponseEntity<User>(currentUser, HttpStatus.OK);
    }
    
    // ------------------- Delete a User-----------------------------------------
    
    @DeleteMapping("/user/{id}")
    public ResponseEntity<?> deleteUser(@PathVariable("id") long id)
    {
        log.info("Fetching & Deleting User with id {}", id);
        
        User user = userService.findById(id);
        if (user == null)
        {
            log.error("Unable to delete. User with id {} not found.", id);
            return new ResponseEntity<>(new CustomErrorType("Unable to delete. User with id " + id + " not found."), HttpStatus.NOT_FOUND);
        }
        userService.deleteUserById(id);
        return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
    }
    
    // ------------------- Delete All Users-----------------------------
    
    @DeleteMapping("/user/")
    public ResponseEntity<User> deleteAllUsers()
    {
        log.info("Deleting All Users");
        
        userService.deleteAllUsers();
        return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
    }
}